﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LapSim {
    class TrackGraphic {
        // Parameters for external use
        public int w = 600, h = 600; // Bitmap resolution
        public double margin = 0.09; // Margin around outside to remain blank, like a border

        // Members for internal use
        private double scale = 0.0001; // Meters / Pixel
        private double cX = 0.0, cY = 0.0; // Center spacial coordinate

        private int mX = 125, mY = 125; // Center coordinate of the bitmap

        private Bitmap bmp;
        private Graphics gfx;

        private Point ToBMPCoord( double x, double y ) {
            return new Point(
                mX + (int)Math.Round( ( (x - cX) * scale ) ),
                mY + (int)Math.Round( ( (-y + cY) * scale ) ) );
        }

        public void DrawTrack( TrackData t ) {
            bmp = new Bitmap( w, h );
            gfx = Graphics.FromImage( bmp );
            gfx.Clear( Color.White );
            gfx.SmoothingMode = SmoothingMode.AntiAlias;

            // Framing info
            mX = w / 2;
            mY = h / 2;

            double minx = double.MaxValue,
                minz = double.MaxValue,
                maxx = double.MinValue,
                maxz = double.MinValue;

            foreach ( Waypoint wp in t.m_waypoints ) {
                minx = Math.Min( wp.pos.x, minx );
                maxx = Math.Max( wp.pos.x, maxx );
                minz = Math.Min( wp.pos.z, minz );
                maxz = Math.Max( wp.pos.z, maxz );

                if ( wp.next == 0 ) break;
            }

            scale = (1.0 / Math.Max( (maxx - minx) / w, (maxz - minz) / h )) / (1.0 + margin);

            cX = (minx + maxx) * 0.5;
            cY = (minz + maxz) * 0.5;

            // Drawing!

            Pen penRoad = new Pen( Color.Red, 1.5f );
            Pen penLine = new Pen( Color.Green, 1.5f  );
            Waypoint wp1, wp2;
            Point p1, p2;

            for ( int i = 0; i <= t.m_waypoints.First().prev; i++ ) {
                wp1 = t.m_waypoints[i];
                wp2 = t.m_waypoints[wp1.next];

                p1 = ToBMPCoord( wp1.GetPathPos().x, wp1.GetPathPos().z );
                p2 = ToBMPCoord( wp2.GetPathPos().x, wp2.GetPathPos().z );

                gfx.DrawLine( penLine, p1, p2 );

                p1 = ToBMPCoord( wp1.GetRoadLeft().x, wp1.GetRoadLeft().z );
                p2 = ToBMPCoord( wp2.GetRoadLeft().x, wp2.GetRoadLeft().z );

                gfx.DrawLine( penRoad, p1, p2 );

                p1 = ToBMPCoord( wp1.GetRoadRight().x, wp1.GetRoadRight().z );
                p2 = ToBMPCoord( wp2.GetRoadRight().x, wp2.GetRoadRight().z );

                gfx.DrawLine( penRoad, p1, p2 );
            }
        }

        public Bitmap GetBmp() {
            return bmp;
        }

        public System.Windows.Media.Imaging.BitmapSource GetBmpSrc() {
            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                  bmp.GetHbitmap(),
                  IntPtr.Zero,
                  System.Windows.Int32Rect.Empty,
                  System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions() );
        }
    }
}
